static int CPXPUBLIC
usersetM      (CPXCENVptr   env,
               void         *cbdata,
               int          wherefrom,
               void         *cbhandle,
               int          *useraction_p
	       )   
{
 
   int status = 0;
   int nodecount,seqnum, itercnt=0;
   int rows, cols;
   int i,j,k;
   double coef, objval, bestobjval;
   double tol = 0.001;
   double   *x   = NULL;
   double *slack   = NULL;
   int cbindIdct = 0;
   int rbindIdct = 0;
   int ybindIdct = 0;
   int      *cstat = NULL;
   int      *rstat = NULL;


   MINFOptr info = (MINFOptr) cbhandle;   //cast the cbhandle

   /* Read in info of coordinates of big M */
   int *flagPtr = info->flagPtr;
   int ni = info -> ni;
   int nj = info -> nj;
   double stepsize = info->stepsize;
   int **bigmRowIdx = info -> bigmRowIdx;
   int **bigmColIdx = info -> bigmColIdx;
   double ***bigmValsPtr = info -> bigmValsPtr;

   CPXLPptr nodelp;      //Can be modified
   CPXCLPptr lp;

   /* Get pointer to root LP problems */
   status = CPXgetcallbacklp(env, cbdata, wherefrom, &lp);
   if ( status )  goto TERMINATE;

   /* Get pointer to node LP problems */
   status = CPXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp);
   if ( status )  goto TERMINATE;

   /* Find out what nodes is being processed */
   status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT, &nodecount);
   if ( status )  goto TERMINATE;

   cols = CPXgetnumcols (env, nodelp);
   rows = CPXgetnumrows (env, nodelp);

   x = (double *) malloc (cols * sizeof (double));
   slack = (double *) malloc (ni *sizeof (double));
   cstat = (int *) malloc (cols*sizeof(int));
   rstat = (int *) malloc (rows*sizeof(int));

   if ( x==NULL || slack == NULL || cstat == NULL || rstat == NULL) {
     fprintf (stderr, "No memory for basis statuses.\n");
     goto TERMINATE;
   }

   //Solve the nodelp
   if (nodecount < 1)   status = CPXprimopt(env, nodelp);
   else                 status = CPXdualopt(env, nodelp);
   if ( status ) {
     fprintf (stdout, "Can't solve the node LP.");
     goto TERMINATE;
   }

   /* Retrieve the solution at the node LP */
   status = CPXgetx(env, nodelp, x, 0, cols-1);
   if ( status ) {
     fprintf (stdout, "Can't get node solution.");
     goto TERMINATE;
   }

   status = CPXgetslack(env, nodelp, slack, bigmRowIdx[0][0], bigmRowIdx[ni-1][0]);
   if ( status ) {
     fprintf (stdout, "Can't get node solution.");
     goto TERMINATE;
   }

   status = CPXgetbase (env,  nodelp, cstat, rstat);
   if ( status ) {
     fprintf (stderr, "Failed to get basis; error %d.\n", status);
     goto TERMINATE;
   }

   status = CPXgetobjval(env, nodelp, &objval);
   if ( status ) {
     fprintf (stdout, "Can't get objective value of node LP.");
     goto TERMINATE;
   }

   double tempslack = 0;

   for(i = 0; i< ni; i++){
     for(j = 0; j< nj; j++){

       status = CPXgetcoef(env, lp, bigmRowIdx[i][j], bigmColIdx[i][j], &coef);
       if(status == 1){
	 printf("I have something wrong here!\n");
	 goto TERMINATE;
       }

       rbindIdct = rstat[bigmRowIdx[i][j]];
       cbindIdct = cstat[bigmColIdx[i][j]];

       // Big M Checking routine
       // Binding
       if( coef + 1.0 < tol || rbindIdct == CPX_BASIC || cbindIdct != CPX_BASIC)  {
	 //rbindIdct == CPX_BASIC
	 itercnt ++; 
	 continue;
       }
      // Unbinding
       else{
	 //	 printf("binding at row %d, col %d, rbindIdct %d, cbindIdct %d, coef %f, binding y%f, tempslack %f \n", bigmRowIdx[i][j], bigmColIdx[i][j], rbindIdct, cbindIdct, coef, x[bigmColIdx[i][j]], tempslack);
	 if(coef - stepsize >= -0.5) coef = coef - stepsize;
	 else coef = -0.5;
	 (*bigmValsPtr)[i][j] = coef;
       }
     }
   }
  // End of checking loop
  if (itercnt == ni*nj){
     goto TERMINATE;
   }
  else{//Go to the next iteration
    *flagPtr = 1;
    
     printf("Slackness when resolve is : \n");
     for(i = 0; i< ni; i++)
       printf("%5.3f ", slack[i]);
     printf("\n");

     printf("big M values:\n");
     for(i = 0; i< ni; i++){
       for(j=0; j<nj; j++)
	 printf("%5.3f ", -(*bigmValsPtr)[i][j]);
     }
     printf("\n");

     printf("Y values: \n");
     for(i = 0; i< ni; i++){
       for(j=0; j<nj; j++)
	 printf("%5.3f ", x[bigmColIdx[i][j]]);
     }
     printf("\n");
     printf("Basic or nonbasis: \n");
     for(i = 0; i< ni; i++){
       for(j=0; j<nj; j++)
	 printf("%d ", cstat[bigmColIdx[i][j]]);
     }
     printf("\n\n");

    /*
    printf("Iteration count is %d and Y when resolving is\n", itercnt);
     for(i=0; i<ni; i++){
       for(j=0; j<nj; j++){
	 printf("%5.3f ", x[bigmColIdx[i][j]]);
       }
     }
    printf("\n");
    */
    goto TERMINATE;
  }

 TERMINATE:
   *useraction_p = CPX_CALLBACK_SET;
   free_and_null ((char **) &x);
   free_and_null ((char **) &rstat);
   free_and_null ((char **) &cstat);
   return (status);

}   //End of callback function usersetM


static int flagcallback (CPXCENVptr env, void *cbdata, int wherefrom,
			 void *cbhandle)
{
  int status = 0;

  //  printf(" I am here !\n");
  MINFOptr info = (MINFOptr) cbhandle;
  int *flagPtr = info->flagPtr;                       // Global Write
 
  if(*flagPtr == 1){
    status = 1;
  }
  return status;
} //End of flag callback function
